/**
 *    https://gitee.com/gitsc/pro-cloud/
 *     @Author Aijm 2929793435@qq.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.cloud.admin.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.utils.JSONUtils;
import com.cloud.admin.beans.dto.TenantDTO;
import com.cloud.admin.beans.dto.UserDTO;
import com.cloud.admin.beans.po.OauthClientDetails;
import com.cloud.admin.service.OauthClientDetailsService;
import com.cloud.admin.service.SysUserService;
import com.cloud.common.cache.constants.CacheScope;
import com.cloud.common.cache.util.RedisUtil;
import com.cloud.common.data.util.IdUtils;
import com.cloud.common.security.util.OauthKeys;
import com.cloud.common.util.base.Result;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cloud.admin.beans.po.SysTenant;
import com.cloud.admin.service.SysTenantService;
import com.cloud.common.util.enums.ResultEnum;
import com.cloud.common.util.util.StrUtils;
import com.cloud.common.util.var.StaticVar;
import com.google.common.collect.Maps;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Map;

/**
 * 租户管理
 *
 * @author Aijm
 * @date 2020-05-25 13:32:23
 */
@RestController
@RequestMapping("/systenant" )
@Api(value = "systenant", tags = "systenant管理")
public class SysTenantController {

    @Autowired
    private SysTenantService sysTenantService;

    @Autowired
    private OauthClientDetailsService oauthClientDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private SysUserService sysUserService;

    /**
     * 分页查询
     * @param page 分页对象
     * @param sysTenant 租户管理
     * @return
     */
    @GetMapping("/page")
    @PreAuthorize("@pms.hasTenantPermissin('admin_systenant_view')")
    public Result getSysTenantPage(Page page, SysTenant sysTenant) {
        return Result.success(sysTenantService.page(page, Wrappers.query(sysTenant).lambda().orderByAsc(SysTenant::getUpdateDate)));
    }


    /**
     * 通过id查询租户管理
     * @param id id
     * @return Result
     */
    @GetMapping("/{id}")
    @PreAuthorize("@pms.hasTenantPermissin('admin_systenant_view')")
    public Result getById(@PathVariable("id") Long id) {
        SysTenant byId = sysTenantService.getById(id);
        TenantDTO tenantDTO = new TenantDTO();
        BeanUtil.copyProperties(byId, tenantDTO);
        OauthClientDetails client = oauthClientDetailsService.getById(byId.getClientId());
        tenantDTO.setOauthClientDetails(client);
        return Result.success(tenantDTO);
    }

    /**
     * 新增租户管理
     * @param tenantDTO 租户管理
     * @return Result
     */
    @PostMapping
    @PreAuthorize("@pms.hasTenantPermissin('admin_systenant_add')")
    public Result save(@RequestBody @Valid TenantDTO tenantDTO) {

        // 租户类型
        if (StaticVar.TENANT_TYPE_TENANT.equals(tenantDTO.getType())) {
            UserDTO userDTO = new UserDTO();
            userDTO.setLoginName(tenantDTO.getLoginName());
            userDTO.setMobile(tenantDTO.getPhone());
            userDTO.setEmail(tenantDTO.getEmail());
            userDTO.setTenantId(tenantDTO.getTenantId());
            // 校验是否能够注册邮箱或者手机号或者登录名
            if(!sysUserService.getCheckUserTenant(userDTO)) {
                return Result.error(ResultEnum.PARAM_REGISTER);
            }
        }
        tenantDTO.setPassword(passwordEncoder.encode(tenantDTO.getPassword()));
        Integer nextTenantId = sysTenantService.getNextTenantId();
        // 对clientSecret加密 和默认值
        OauthClientDetails oauthClientDetails = tenantDTO.getOauthClientDetails();
        oauthClientDetails.setClientSecret(passwordEncoder.encode(oauthClientDetails.getClientSecret()));
        oauthClientDetails.setAccessTokenValidity(OauthKeys.ACCESS_TOKEN_VALIDITY);
        oauthClientDetails.setRefreshTokenValidity(OauthKeys.REFRESH_TOKEN_VALIDITY);
        oauthClientDetails.setTenantId(nextTenantId);
        oauthClientDetails.setClientId(String.valueOf(IdUtils.getNextId()));

        tenantDTO.setClientId(oauthClientDetails.getClientId());
        tenantDTO.setTenantId(nextTenantId);
        return Result.success(sysTenantService.saveSysTenant(tenantDTO));
    }

    /**
     * 修改租户管理
     * @param tenantDTO 租户管理
     * @return Result
     */
    @PutMapping
    @PreAuthorize("@pms.hasTenantPermissin('admin_systenant_edit')")
    public Result updateById(@RequestBody @Valid TenantDTO tenantDTO) {
        SysTenant byId = sysTenantService.getById(tenantDTO.getId());
        RedisUtil.remove(CacheScope.TENTANT_KEY.getCacheName(),byId.getClientId());
        tenantDTO.setTenantId(null);
        OauthClientDetails oauthClientDetails = tenantDTO.getOauthClientDetails();

        // 对密码加密
        if (StrUtils.isNotBlank(oauthClientDetails.getClientSecret())) {
            oauthClientDetails.setClientSecret(passwordEncoder.encode(oauthClientDetails.getClientSecret()));
        }
        // 对oauthClientDetails 操作
        oauthClientDetails.setClientId(byId.getClientId());
        oauthClientDetailsService.updateById(oauthClientDetails);
        // 对租户表操作
        return Result.success(sysTenantService.updateById(tenantDTO));
    }

    /**
     * 通过id删除租户管理
     * @param id id
     * @return Result
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasTenantPermissin('admin_systenant_del')")
    public Result removeById(@PathVariable Long id) {
        SysTenant byId = sysTenantService.getById(id);
        RedisUtil.remove(CacheScope.TENTANT_KEY.getCacheName(), byId.getClientId());
        return Result.success(sysTenantService.removeById(id));
    }

}